package com.mingqijia.gassafety.webserver.service.impl;

import cn.hutool.core.date.BetweenFormatter;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.gap.basic.exception.BizException;
import com.mingqijia.gassafety.db.entity.DeviceState;
import com.mingqijia.gassafety.db.entity.Dtu;
import com.mingqijia.gassafety.db.entity.SmartKitchenLog;
import com.mingqijia.gassafety.db.entity.WorkOrderHistory;
import com.mingqijia.gassafety.db.mapper.DictionaryMapper;
import com.mingqijia.gassafety.db.mapper.DtuMapper;
import com.mingqijia.gassafety.shared.constant.EquipmentType;
import com.mingqijia.gassafety.webserver.request.console.sk.ConsoleSkAlarmStatusNoticeRequest;
import com.mingqijia.gassafety.webserver.response.sk.ConsoleSkAlarmStatusNoticeResponse;
import com.mingqijia.gassafety.webserver.service.SmartKitchenLogService;
import com.mingqijia.gassafety.shared.constant.AsstConstants;
import com.mingqijia.gassafety.shared.constant.Constants;
import com.mingqijia.gassafety.shared.constant.DeviceType;
import com.mingqijia.gassafety.shared.utils.ApplicationUtils;
import com.mingqijia.gassafety.shared.utils.HeaderUtil;
import com.mingqijia.gassafety.shared.utils.HttpUtil;
import com.mingqijia.gassafety.shared.utils.commonUtils.SnowflakeUtil;
import com.mingqijia.gassafety.webserver.feign.ConsoleSkFeignClient;
import com.mingqijia.gassafety.webserver.request.console.sk.ConsoleSkUpdateRequest;
import com.mingqijia.gassafety.webserver.request.workorder.asst.AsstOrderCreateRequest;
import com.mingqijia.gassafety.webserver.request.workorder.asst.OrderDeviceRequest;
import com.mingqijia.gassafety.webserver.request.workorder.asst.WorkOrderCreateRequest;
import com.mingqijia.gassafety.webserver.response.sk.ConsoleSkUpdateResponse;
import com.mingqijia.gassafety.webserver.response.workorder.asst.AsstWorkOrderResponse;
import com.mingqijia.gassafety.webserver.service.CompanyService;
import com.mingqijia.gassafety.webserver.service.SmartKitchenService;
import com.mingqijia.gassafety.webserver.service.workorder.AsstWorkOrderService;
import com.mingqijia.gassafety.webserver.service.workorder.WorkOrderHistoryService;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.util.StringUtil;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import static com.mingqijia.gassafety.webserver.constant.DeviceConstant.*;

/**
 * @author zhangfei
 * @version 1.0.0
 * @ClassName SmartKitchenServiceImpl.java
 * @Description TODO
 * @createTime 2023年06月27日
 */
@Service
@Slf4j
public class SmartKitchenServiceImpl implements SmartKitchenService {

    @Autowired
    AsstWorkOrderService asstWorkOrderService;
    @Autowired
    ConsoleSkFeignClient client;
    @Autowired
    HttpUtil httpUtil;
    @Autowired
    SmartKitchenLogService smartKitchenLogService;
    @Autowired
    CompanyService companyService;
    @Autowired
    HeaderUtil headerUtil;
    @Autowired
    WorkOrderHistoryService workOrderHistoryService;
    @Value(value = "${asst.workOrder.doamin.url}")
    String workOrderUrl;
    private final static String split_m = ":";

    @Autowired
    RedisTemplate redisTemplate;

    @Autowired
    DictionaryMapper dictionaryMapper;

    @Autowired
    DtuMapper dtuMapper;

    private ExecutorService executor = Executors.newFixedThreadPool(200);
    /**
     * 智慧厨房转工单处理
     *
     * @param req
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void create(WorkOrderCreateRequest req) {
        String spId = ApplicationUtils.getWorkingSpId();
        if (req.getStatus() != 0) {
            LambdaQueryWrapper<SmartKitchenLog> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(SmartKitchenLog::getRecordId, req.getId()).eq(SmartKitchenLog::getAppealType, 0)
                    .eq(SmartKitchenLog::getIsDeleted, 0);
            List<SmartKitchenLog> list = smartKitchenLogService.list(queryWrapper);
            if (!CollectionUtils.isEmpty(list)) {
                throw new BizException("已完成或处理中");
            }
        }
        //已处理
        if (req.getStatus() == 1) {
            log.info("create-已处理:{}",JSONObject.toJSONString(req));
            SmartKitchenLog appealLog = new SmartKitchenLog();
            appealLog.setRecordId(req.getId());
            appealLog.setAppealStatus(Constants.APPEAL_STATUS_2);
            appealLog.setAppealResult(req.getAppealResult());
            appealLog.setSpId(spId);
            appealLog.setUserName(ApplicationUtils.getWorkingUser().getName());
            appealLog.setUserAccount(ApplicationUtils.getWorkingUser().getUsername());
            appealLog.setAppealType(0);
            appealLog.setBizType(req.getBizType());
            log.info("新增时刻助手工单诉求记录：" + appealLog.toString());
            smartKitchenLogService.save(appealLog);
            ConsoleSkUpdateRequest request = new ConsoleSkUpdateRequest();
            request.setId(req.getId());
            request.setDealStatus(req.getStatus()==1?2:1);
            log.info("alarmSOSUpdate-request:{}",JSONObject.toJSONString(request));
            ConsoleSkUpdateResponse consoleSkUpdateResponse = client.alarmSOSUpdate(request);
            log.info("alarmSOSUpdate-consoleSkUpdateResponse:{}",JSONObject.toJSONString(consoleSkUpdateResponse));
        } else if (req.getStatus() == 2) {
            log.info("create-转工单:{}",JSONObject.toJSONString(req));
            //转工单
            WorkOrderCreateRequest params = new WorkOrderCreateRequest();
            BeanUtils.copyProperties(req, params);
            Long workorderId = createOrder(params);
            if (workorderId != null) {
                SmartKitchenLog appealLog = new SmartKitchenLog();
                appealLog.setWorkorderId(workorderId);
                appealLog.setRecordId(req.getId());
                appealLog.setAppealStatus(Constants.APPEAL_STATUS_1);
                appealLog.setSpId(spId);
                appealLog.setUserName(ApplicationUtils.getWorkingUser().getName());
                appealLog.setUserAccount(ApplicationUtils.getWorkingUser().getUsername());
                appealLog.setAppealResult(req.getAppealResult());
                appealLog.setAppealType(0);
                appealLog.setBizType(req.getBizType());
                appealLog.setRemark(req.getUserRemark());
                log.info("新增智慧厨房设备诉求记录：" + appealLog.toString());
                smartKitchenLogService.save(appealLog);
            }
        } else {
            WorkOrderCreateRequest params = new WorkOrderCreateRequest();
            BeanUtils.copyProperties(req, params);
            createOrder(params);
        }
    }


    public Long createOrder(WorkOrderCreateRequest params) {
        String spId = ApplicationUtils.getWorkingSpId();
        String orgCode = companyService.getOrgCode(spId,params.getSubsCode());
        String woSeq = workOrderHistoryService.WORK_ORDER_NO_PREFIX + SnowflakeUtil.getSnowflakeId();
        List<AsstOrderCreateRequest> list = new ArrayList<>();
        AsstOrderCreateRequest req = new AsstOrderCreateRequest();
        BeanUtils.copyProperties(params, req);
        req.setFromSystem(4);
        req.setOrgCode(orgCode);
        //发起的智慧厨房设备
        List<OrderDeviceRequest> orderDeviceList = new ArrayList<>();
        OrderDeviceRequest orderDeviceRequest = new OrderDeviceRequest();
        orderDeviceRequest.setEquipmentType(DeviceType.parse(params.getDeviceType()).getName());
        orderDeviceRequest.setIMEI(params.getImei());
        orderDeviceRequest.setAlarmStartTime(params.getAlarmTime());
        orderDeviceRequest.setAlarmEndTime(params.getAlarmEndTime());
        orderDeviceRequest.setAlarmState(params.getBizType()==7?(params.getAlarmType()==6?
                "防拆报警":"密码错误连续5次"):"报警");
        orderDeviceRequest.setDeviceName(params.getDeviceName());
        orderDeviceRequest.setInstallPosition(params.getInstallPosition());
        String state="";
        if (params.getDeviceType()==1){
            state="30min按键"+params.getAlarmCount()+"次";
        }else if (params.getDeviceType()==2||params.getDeviceType()==3){

            Date start=DateUtil.parse(params.getAlarmTime(),"yyyy-MM-dd HH:mm:ss");
            Date end=new Date();
            if (!StringUtils.isEmpty(params.getAlarmEndTime())){
                end=DateUtil.parse(params.getAlarmEndTime(),"yyyy-MM-dd HH:mm:ss");
            }
            state=getDurationDate(start, end);
        }
        orderDeviceRequest.setAlarmDurationState(state);
        orderDeviceList.add(orderDeviceRequest);
        req.setOrderDeviceList(orderDeviceList);
        req.setAddress(params.getAddress());
        req.setLocation(params.getLon() + "," + params.getLat());
        list.add(req);
        log.info("createOrder-request:{}",JSONObject.toJSONString(list));
        String body = httpUtil.getBody(JSONObject.toJSONString(list), workOrderUrl + AsstConstants.ORDER_CREATE_URL, null);
        log.info("createOrder-response:{}",JSONObject.toJSONString(body));
        JSONObject jsonObject = JSONObject.parseObject(body);
        if (jsonObject.get("code").equals(0)) {
            AsstWorkOrderResponse asstWorkOrder = JSONObject.toJavaObject((JSON) jsonObject.getJSONArray("data").get(0), AsstWorkOrderResponse.class);
            ConsoleSkUpdateRequest request = new ConsoleSkUpdateRequest();
            request.setId(params.getId());
            request.setDealStatus(1);
            request.setContact(params.getCustName());
            request.setContactAddress(params.getAddress());
            request.setContactPhone(params.getPhone());
            request.setResult(params.getAppealResult());
            request.setWorkOrderNo(asstWorkOrder.getOrderNo());
            log.info("alarmSOSUpdate-request:{}",JSONObject.toJSONString(request));
            ConsoleSkUpdateResponse consoleSkUpdateResponse = client.alarmSOSUpdate(request);
            log.info("alarmSOSUpdate-consoleSkUpdateResponse:{}",JSONObject.toJSONString(consoleSkUpdateResponse));
            WorkOrderHistory history = new WorkOrderHistory();
            history.setWoSeq(woSeq);
            history.setDeviceId(params.getImei());
            history.setOrderNo(asstWorkOrder.getOrderNo());
            history.setWorkSystem(0);
            history.setDeviceStatus(6);
            history.setReason("报警");
            history.setSpId(spId);
            workOrderHistoryService.save(history);
            return history.getId();
        } else {
            throw new BizException(jsonObject.get("msg").toString());
        }
    }
    /**
     * 计算区间间隔 00:00:00
     *
     * @param startDate
     * @param endDate
     */
    private String getDurationDate(Date startDate, Date endDate) {
        String formatBetween = DateUtil.formatBetween(endDate, startDate, BetweenFormatter.Level.SECOND);
        System.out.println(formatBetween);
        formatBetween = formatBetween.replace(BetweenFormatter.Level.SECOND.getName(), "");
        if (formatBetween.contains(BetweenFormatter.Level.MINUTE.getName())) {
            formatBetween = formatBetween.replace(BetweenFormatter.Level.MINUTE.getName(), split_m);
        } else {
            formatBetween = "00" + split_m + formatBetween;
        }
        if (formatBetween.contains(BetweenFormatter.Level.HOUR.getName())) {
            formatBetween = formatBetween.replace(BetweenFormatter.Level.HOUR.getName(), split_m);
        } else {
            formatBetween = "00" + split_m + formatBetween;
        }
        if (formatBetween.contains(BetweenFormatter.Level.DAY.getName())) {
            formatBetween = formatBetween.substring(formatBetween.indexOf(BetweenFormatter.Level.DAY.getName()), formatBetween.length());
            formatBetween = "59" + formatBetween.substring(formatBetween.indexOf(split_m), formatBetween.length());
        }
        String format = "";
        String[] split = formatBetween.split(split_m);
        for (int i = 0; i < split.length; i++) {
            String s = split[i] + split_m;
            if (s.length() < 3 && s.length() == 2) {
                format = format + "0" + s;
            } else {
                format = format + s;
            }
        }
        if (format.substring(format.length() - 1, format.length()).contains(split_m)) {
            format = format.substring(0, format.length() - 1);
        }
        return format;
    }

    @Override
    public void handleBrokenSyncAlarmStatusNotice(Dtu dtu,DeviceState deviceState, DeviceState prepareDeviceState) {
        try {
            //家用燃气报警器 上次为报警 本次非报警
            if (EquipmentType.HOME_GAS_DETECTOR.getCode().equals(dtu.getEquipmentType())
                    && (DEVICE_STATUS_2.equals(deviceState.getDeviceStatus()) ||
                    DEVICE_STATUS_3.equals(deviceState.getDeviceStatus())
                    || DEVICE_STATUS_6.equals(deviceState.getDeviceStatus()))
                    && !DEVICE_STATUS_2.equals(prepareDeviceState.getDeviceStatus())
                    && !DEVICE_STATUS_3.equals(prepareDeviceState.getDeviceStatus())
                    && !DEVICE_STATUS_6.equals(prepareDeviceState.getDeviceStatus())) {
                syncAlarmStatusNotice(dtu, 0);
            }
        }catch (Exception e){
            log.error("handleBrokenSyncAlarmStatusNotice:",e);
        }
    }

    @Override
    public void syncAlarmStatusNotice(Dtu dtu, Integer alarmStatus) {
        try {
            if (EquipmentType.HOME_GAS_DETECTOR.getCode().equals(dtu.getEquipmentType())) {
                String imei = dtu.getIMEI();
                log.info("设备：{}同步给智慧厨房", imei);
                executor.submit(new Runnable() {
                    @Override
                    public void run() {
                        try {
                            ConsoleSkAlarmStatusNoticeRequest request = new ConsoleSkAlarmStatusNoticeRequest();
                            request.setDeviceId(imei);
                            request.setAlarmStatus(String.valueOf(alarmStatus));
                            log.info("ConsoleSkAlarmStatusNoticeRequest:{}", JSONObject.toJSONString(request));
                            ConsoleSkAlarmStatusNoticeResponse response = client.alarmStatusNotice(request);
                            log.info("ConsoleSkAlarmStatusNoticeResponse:{}", JSONObject.toJSONString(response));
                        } catch (Exception e) {
                            log.error("同步设备报警信息到智慧厨房报错", e);
                        }
                    }
                });
            }
        }catch (Exception e){
            log.error("syncAlarmStatusNotice:", e);
        }
    }

    /**
     * 获取字典中的需要同步给智慧厨房的imei号
     *
     * @return
     */
    private List<String> getSyncAlarmStatusCodes(){
        Object imeiObj = redisTemplate.opsForValue().get(Constants.SYNC_ALAM_TO_SK_IMEIS_REDIS_KEY);
        if (!ObjectUtil.isEmpty(imeiObj)){
            String imeiStr = imeiObj.toString();
            return Arrays.asList(imeiStr.split(","));
        }
        List<String> imeiArr = dictionaryMapper.selectSyncAlarmCodes();
        if( imeiArr.size()>0 ){
            String[] tmp = imeiArr.toArray(new String[imeiArr.size()]);
            String imeiStr = StringUtil.join(tmp,",");
            redisTemplate.opsForValue().set(Constants.SYNC_ALAM_TO_SK_IMEIS_REDIS_KEY,imeiStr);
        }
        return imeiArr;
    }
}
